package org.depsea.oss.config.tenant;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import lombok.Getter;
import org.depsea.oss.client.CustomerBucketOssTemplate;
import org.depsea.oss.client.OssTemplate;
import org.depsea.oss.client.OssType;
import org.depsea.oss.client.PresignedUrlGenerator;
import org.depsea.oss.client.aliyun.AliyunCustomerBucketOssTemplate;
import org.depsea.oss.client.aliyun.AliyunOssTemplate;
import org.depsea.oss.client.aliyun.AliyunPresignedUrlGenerator;
import org.depsea.oss.filter.FileUploadFilter;
import org.depsea.oss.model.OssConfigParser;
import org.depsea.oss.strategy.FilenameHandleStrategy;
import org.springframework.context.ApplicationContext;

import java.util.List;
import java.util.Map;

public class AliyunTenantOssConfiguration extends AbstractTenantConfiguration implements TenantOssConfiguration {

    private final OssConfigParser ossConfigParser;

    private OSSClient ossClient;

    @Getter
    private OssTemplate ossTemplate;

    @Getter
    private CustomerBucketOssTemplate customerBucketOssTemplate;

    @Getter
    private PresignedUrlGenerator presignedUrlGenerator;

    public AliyunTenantOssConfiguration(Map<String, String> config, ApplicationContext applicationContext) {
        super(applicationContext);
        this.ossConfigParser = new OssConfigParser(config);
        this.init();
    }

    @Override
    public OssType getOssType() {
        return OssType.ALIYUN;
    }

    private void init() {
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(
                ossConfigParser.getAccessKey(),
                ossConfigParser.getSecretKey()
        );
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        this.ossClient = new OSSClient(ossConfigParser.getEndpoint(), credentialsProvider, clientConfiguration);

        FilenameHandleStrategy filenameHandleStrategy = this.getFilenameHandleStrategy();
        List<FileUploadFilter> uploadFilters = this.getFilterList();

        createOssTemplate(this.ossClient, filenameHandleStrategy, uploadFilters);
        createCustomerBucketOssTemplate(this.ossClient, filenameHandleStrategy, uploadFilters);
        this.createPresignedUrlGenerator(this.ossClient);
    }

    private void createOssTemplate(OSSClient ossClient, FilenameHandleStrategy filenameHandleStrategy, List<FileUploadFilter> uploadFilters) {

        AliyunOssTemplate aliyunOssTemplate = new AliyunOssTemplate(ossClient, ossConfigParser.getDefaultBucketName());
        if (filenameHandleStrategy != null) {
            aliyunOssTemplate.setFilenameHandleStrategy(this.getFilenameHandleStrategy());
        }
        aliyunOssTemplate.addFilters(uploadFilters);
        this.ossTemplate = aliyunOssTemplate;
    }

    private void createCustomerBucketOssTemplate(OSSClient ossClient, FilenameHandleStrategy filenameHandleStrategy, List<FileUploadFilter> uploadFilters) {

        AliyunCustomerBucketOssTemplate aliyunOssTemplate = new AliyunCustomerBucketOssTemplate(ossClient);
        if (filenameHandleStrategy != null) {
            aliyunOssTemplate.setFilenameHandleStrategy(this.getFilenameHandleStrategy());
        }
        aliyunOssTemplate.addFilters(uploadFilters);
        this.customerBucketOssTemplate = aliyunOssTemplate;
    }

    private void createPresignedUrlGenerator(OSSClient ossClient) {
        this.presignedUrlGenerator = new AliyunPresignedUrlGenerator(ossClient, ossConfigParser.getDefaultBucketName());
    }

    @Override
    public void close() {
        this.ossClient.shutdown();
    }
}
